package services

import (
	"context"
	store "eth-client-demo/contracts"
	"fmt"
	"log"
	"math/big"

	"github.com/ethereum/go-ethereum/accounts/abi/bind"
	"github.com/ethereum/go-ethereum/common"
	"github.com/ethereum/go-ethereum/core/types"
)

// TransferETH ETH转账
func (ec *EthClient) TransferETH(value *big.Int, to string) error {
	//读取应用账号随机数
	nonce, err := ec.Client.PendingNonceAt(context.Background(), ec.Address)
	if err != nil {
		return err
	}
	//燃气上限
	gasLimit := uint64(21000) // in units
	//燃气价格
	gasPrice, err := ec.Client.SuggestGasPrice(context.Background())
	if err != nil {
		return err
	}
	tx := types.NewTransaction(nonce, common.HexToAddress(to), value, gasLimit, gasPrice, nil)
	//签名
	signedTx, err := types.SignTx(tx, types.NewEIP155Signer(ec.ChainID), ec.PrivateKey)
	if err != nil {
		return err
	}
	//开始发送交易
	err = ec.Client.SendTransaction(context.Background(), signedTx)
	if err != nil {
		return err
	}
	fmt.Printf("交易哈希: %s\n", signedTx.Hash().Hex())
	return nil
}

// DeployContract 部署合约
func (ec *EthClient) DeployContract() error {
	//读取应用账号随机数
	nonce, err := ec.Client.PendingNonceAt(context.Background(), ec.Address)
	if err != nil {
		return err
	}
	//燃气上限
	gasLimit := uint64(300000) // in units
	//燃气价格
	gasPrice, err := ec.Client.SuggestGasPrice(context.Background())
	if err != nil {
		return err
	}
	//创建交易授权
	auth, err := bind.NewKeyedTransactorWithChainID(ec.PrivateKey, ec.ChainID)
	if err != nil {
		log.Fatal(err)
	}
	auth.Nonce = big.NewInt(int64(nonce))
	auth.Value = big.NewInt(0) // in wei
	auth.GasLimit = gasLimit   // in units
	auth.GasPrice = gasPrice
	address, tx, instance, err := store.DeployStore(auth, ec.Client, "1.0")
	if err != nil {
		return err
	}
	fmt.Println("合约地址:", address.Hex())
	fmt.Println("交易哈希:", tx.Hash().Hex())
	_ = instance // 合约实例
	return nil
}

// ExecuteTheContract 执行合约
func (ec *EthClient) ExecuteTheContract(tranAddress string) (*types.Transaction, error) {
	nonce, err := ec.Client.PendingNonceAt(context.Background(), ec.Address)
	if err != nil {
		return nil, err
	}
	contractAddr := common.HexToAddress(tranAddress)
	//燃气上限
	gasLimit := uint64(300000) // in units
	//燃气价格
	gasPrice, err := ec.Client.SuggestGasPrice(context.Background())
	if err != nil {
		return nil, err
	}
	//创建合约实例
	instance, _ := store.NewStore(contractAddr, ec.Client)
	//  准备数据
	key := [32]byte{}
	value := [32]byte{}
	copy(key[:], []byte("name"))
	copy(value[:], []byte("Alice"))
	auth, _ := bind.NewKeyedTransactorWithChainID(ec.PrivateKey, ec.ChainID)
	auth.Nonce = big.NewInt(int64(nonce)) // 交易序号
	auth.GasLimit = gasLimit              // 交易 Gas 限制
	auth.GasPrice = gasPrice              // 交易 Gas 价格
	auth.Value = big.NewInt(0)            // 交易附带的 ETH
	tx, err := instance.SetItem(auth, key, value)
	if err != nil {
		return nil, err
	}
	return tx, nil
}
